package com.brooks.demo.program.p1;

import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.locks.LockSupport;

/**
 * 面试题
 * 实现一个容器，提供两个方法，add,size
 * 写两个线程，线程1往容器里添加10个元素，线程2实现监控元素的个数，当个数到5时，线程2给出提示并结束
 *
 * 这里利用了LockSupport可以阻塞线程的特点，t2先执行，然后park阻塞，t1开始添加元素，到5个后，t1 unpark(t2)让t2
 * 继续执行，同时t1 park阻塞，t2执行完之后，t2 unpark(t1)让t1继续执行直到结束
 * @Author mihutu
 * @Date 2020/10/20 11:11
 * @Version 1.0
 */
public class DemoLockSupport {
    /**
     * 这里使用同步容器来保证数据一致,否则会出现脏读的情况
     */
    volatile List list = Collections.synchronizedList(new LinkedList<>());

    public void add(Object o) {
        list.add(o);
    }

    public int size() {
        return list.size();
    }
    static Thread t1 = null,t2=null;
    public static void main(String[] args) {
        DemoLockSupport v = new DemoLockSupport();

        //监控数量的线程
        t2 = new Thread(() -> {
            System.out.println("t2监控已启动");
            if (v.size() != 5) {
                LockSupport.park();
            }
            System.out.println("已经到第5个了，我结束了");
            LockSupport.unpark(t1);
        }, "t2");
        //添加元素的线程
       t1 = new Thread(() -> {
            System.out.println("t1已启动，准备添加元素");
            for (int i = 0; i < 10; i++) {
                v.add(new Object());
                System.out.println("添加了第" + i + "个元素");
                if(v.size()==5){
                    LockSupport.unpark(t2);
                    LockSupport.park();
                }
            }
            System.out.println("t1 结束");
        }, "t1");
        t2.start();
        t1.start();
    }
}
